/********************************************************************************
Copyright (C), Sinowealth Electronic. Ltd.
Author: 	Sino
Version: 	V0.0
Date: 		2014/05/30
History:
	V0.0		2014/05/30		 Preliminary
********************************************************************************/
#include "system.h"
#include "ISP.h"
// 003 4串板子只有 UART0 UART2 可用。
// 003A 8串板子	UART0-DEBUG  UART1-BT  UART2-485

/*******************************************************************************
Function: InitUART0()
Description: Init UART1  
Input:  NULL
Output: NULL
Others:
*******************************************************************************/
void InitUART1(void)
{
	UART1CR = 0x01;

	BANK1_SEL;_nop_();
	PCON1 = 0x00;	
	SCON1 = 0x50;		//配置Uart工作在模式1
	SBRTH1 = 0xFF;		//配置波特率参数，波特率115200
	SBRTL1 = 0xF3;		//计算公式：(int)X=FSY/(16*波特率) ;  SBRT=32768-X  ;   SFINE=（FSY/波特率）-16*X   FSY=24M
	SFINE1 = 0x04;
	SADDR1 = 0x0A;
	SADEN1 = 0xFF;

	ucUart1BufPT = 0;
	ucUart1TimeoutCnt = 0;
	BANK0_SEL;
#if 1
	EA = 0;
	IEN2 |= 0x01;						//Enable UART2 Interrupt	LZH

	IPL0 = 0x10;
	IPH0 = 0x90;
	IPL1 = 0x00;
	IPH1 = 0x00;						//set uart priority = 3, other interrupt priority  = 0
	EA = 1;	
#endif
}

/*******************************************************************************
Function:Uart1ReadInfo() 
Description:  Read the information: Battery Info, MCU Info, MTP Info
Input:  *prt---Data storage address
Output: NULL
Others:
*******************************************************************************/
void Uart1ReadInfo(U8 xdata *ptr, U8 CMD, U8 Len)
{
	U8 xdata i;
	U16 xdata CRC16heck=0;
	
	if (Len > 140)
	{
		Len = 1;
	}
	BANK1_SEL;REN1=0;RI1=0;BANK0_SEL;//_nop_();
	UART485_DE = 1;				//485  Send
#if 1
	ucUart1Buf[UART1_SLAVE_ADDR] = 0x01;
	ucUart1Buf[UART1_CMD_NO] = CMD;
	ucUart1Buf[UART1_LENGTH] = Len;
	for(i=0; i<Len; i++)
	{
		RSTSTAT = 0x00;
		ucUart1Buf[UART1_DATA + i] = *ptr;
		ptr++;
	}
	CRC16heck = CRC16(&ucUart1Buf,ucUart1Buf[UART1_LENGTH]+3);
	ucUart1Buf[3+ucUart1Buf[UART1_LENGTH]] = CRC16heck;
	ucUart1Buf[4+ucUart1Buf[UART1_LENGTH]] = CRC16heck>>8;
	ucUart1SndLength = 4+ucUart1Buf[UART1_LENGTH];
#else
	for(i=0; i<Len; i++)
	{
		RSTSTAT = 0x00;
		ucUart1Buf[7 + i] = *ptr;
		ptr++;
	}
	ucUart1Buf[0] = 0x01;
	ucUart1Buf[6] = Len;
	CRC16heck = CRC16(&(ucUart1Buf + 7), Len);
	ucUart1Buf[7+Len] = CRC16heck;
	ucUart1Buf[8+Len] = CRC16heck>>8;
	ucUart1SndLength = 8 + Len;
#endif
	ucUart1BufPT = 0;
	UART1_SEND_DATA;			//Start Send Data; Set UART REG
}

/*******************************************************************************
Function:Uart1LogProcess() 
Description:  Processing Uart read command  
Input:   NULL
Output: NULL
Others:
*******************************************************************************/
void Uart1LogProcess(void)
{
	static U8 xdata Num=60;
	if(Num > 5)
	{
		Num = 0;
		// Uart1ReadInfo((U8 xdata *)&Info, 1, sizeof(SYSINFOR));	//Send String

		Uart1AT_IMEIQurry("123456789123456789\r\n", 20);
	}
	Num++;
}

/*******************************************************************************
Function:Uart1PCSSend() 
Description:  Processing Uart read command  
Input:   NULL
Output: NULL
Others:
*******************************************************************************/
void Uart1PCSSend(void)
{
	PCSINFO xdata PCSInfo;
	U16 xdata Warning=0, status=0;
#if 0
	PCSInfo.Current 			= (S16)(Info.slCurr/10);
	PCSInfo.VoltageOfPack 		= Info.ulVoltage/10;
	PCSInfo.SOC 				= Info.uiRSOC;
	PCSInfo.SOH 				= 100;
	PCSInfo.RemainCapacity 		= Info.ulRC/10;
	PCSInfo.FullCapacity 		= Info.ulFCC/10;
	PCSInfo.DesignCapacity 		= Info.ulFCC/10;
	PCSInfo.BatteryCycleCounts 	= Info.uiCycleCount;
	PCSInfo.Reserved 			= 0xff;
	PCSInfo.WarningFlag 		= 0x00;									
	PCSInfo.ProtectionFlag 		= 0x00;
	PCSInfo.StatusFaultFlag 	= 0x00;
	PCSInfo.BalanceStatus 		= 0x00;
#else
	Warning = 0x0000 | (bFC?1:0) | (bFD?(1<<1):0);

	if(bCHGING)
	{
		status |= 0x02; 
		status |= (1<<6); 
	}else if(bDSGING)
	{
		status |= 0x03; 
		status |= (1<<5); 
	}
	status |= bBalanceFlg?(1<<3):0;

	PCSInfo.Status								= status;
	PCSInfo.Error								= 0x00;
	PCSInfo.SOC									= Info.uiRSOC;
	PCSInfo.Voltage								= Info.ulVoltage/10;
	PCSInfo.Current								= Info.slCurr/10;
	PCSInfo.Temperature							= Info.uiTemp1;
	PCSInfo.MaxChargeDischargeCurrent			= 20000;
	PCSInfo.GaugeRM								= Info.ulRC/10;
	PCSInfo.GaugeFCC							= Info.ulFCC/10;
	PCSInfo.YW_FW								= 0x0102;
	PCSInfo.Delta								= Info.ulVoltage/10;
	PCSInfo.CycleCount							= Info.uiCycleCount;
	PCSInfo.RSVDForMasterBox					= 0x00;
	PCSInfo.SOH									= 0x00ff;
	PCSInfo.CV_Voltage							= 3000;
	PCSInfo.Warning								= Warning;
	PCSInfo.AlphaMaxDischargeCurrent			= 20000;
	PCSInfo.AlphaExtendedError					= 0x00;
#endif
	Uart1ReadInfo((U8 xdata *)&PCSInfo, 0x03, sizeof(PCSINFO));	//Send String
}

/*******************************************************************************
Function:Uart1AT_IMEIQurry() 
Description:  
Input:   NULL
Output: NULL
Others:
*******************************************************************************/
void Uart1AT_IMEIQurry(U8 *ptr, U8 Len)
{
	U8 xdata i=0;

	if (Len > 140)
	{
		Len = 1;
	}
	BANK1_SEL;REN1=0;RI1=0;BANK0_SEL;//_nop_();
	UART485_DE = 1;				//485  Send

	for(i=0; i<Len; i++)
	{
		ucUart1Buf[i] = *(ptr+i);
	}
	ucUart1SndLength = Len-1;
	ucUart1BufPT = 0;
	UART1_SEND_DATA;			//Start Send Data; Set UART REG
}

/*******************************************************************************
Function:Uart1RdCmdProcess() 
Description:  Processing Uart read command  
Input:   NULL
Output: NULL
Others:
*******************************************************************************/
void Uart1RdCmdProcess(void)
{
     U16 xdata *rdaddr;
	 U16 xdata temp=0;
    
	rdaddr = (U16 *)(ucUart1Buf+2);
	temp = *rdaddr;

    switch(temp)
    {
        case 0x01:
        break;
        case 0x02:
        break;
        case 0x03:
        break;
        case 0x13:
			// Uart1LogProcess();
			Uart1PCSSend();
        break;
        default:    //read extern EEPRom data
			break;
    }
}

/*******************************************************************************
Function:  InterruptUART()
Description:  Receive and transmit data via UART
	ucUartBuf[0]--Slave Addr
	ucUartBuf[1]--CMD No.
	ucUartBuf[2]--Offset
	ucUartBuf[3]--Data Length
	ucUartBuf[4...]--Data
Input:	 	
Output: 
Others:
*******************************************************************************/
#if 1
void InterruptUART1(void) interrupt 15
{
	U16 i=0, Crc=0, CrcCheck=0;

	_push_(INSCON);
    BANK1_SEL;
	if(RI1)                              //RT1 interrupt means MCU recept data though UART
	{
		ucUart1Buf[ucUart1BufPT] = SBUF1;                  //transfer SBUF to the ucUartBuf
		ucUart1BufPT++;
		if(ucUart1BufPT >= 149)
		{
			ucUart1BufPT = 0;
		}
#ifndef 	PCS_485
		if(ucUart1BufPT > 2)
		{
			if((ucUart1Buf[ucUart1BufPT-2] == 0x0D)&&(ucUart1Buf[ucUart1BufPT-1] == 0x0A))
			{
				ATCmdReceive();
			}
		}
#else
		if(ucUart1BufPT == 2)
		{
			if(ucUart1Buf[UART1_SLAVE_ADDR] == SADDR1)      //received first data is not the slave ADDR
			{
				if(ucUart1Buf[UART1_CMD_NO] == 0x03)         //bit 7 of UartADDR is R/W 0--R, 1--W
				{
					bUart1ReadFlg = 1;					//this communication is read
				}
				else if(ucUart1Buf[UART1_CMD_NO] == 0x01) 
				{
					bUart1WriteFlg = 1;					//this communication is write        
				}
			}
			else
			{
				ucUart1BufPT = 0;                       //ucUartBufPT reset to 0  
			}
		}
		if(bUart1ReadFlg)
		{
			if(ucUart1BufPT == 8)
			{
				Crc = CRC16(ucUart1Buf, 6);
				CrcCheck = ucUart1Buf[6];
				CrcCheck |= ucUart1Buf[7] << 8;

				if(Crc == CrcCheck)
				{
					Uart1RdCmdProcess();                 //Read the command process	
				}
			}
		}
		if(bUart1WriteFlg)
		{
			if(ucUart1BufPT > (ucUart1Buf[UART_LENGTH]+3))        //If a write operation, and complete all the data has been received
			{
				// UartWrCmdProcess();					//Write the command peocess
				bUart1WriteFlg = 0;					//PC write MCU communiaction over
				ucUart1BufPT = 0;
			}
		}
#endif
		RI1 = 0;
		// bUartSndAckFlg = 0;
	}
	if(TI1)
	{
		ucUart1BufPT++;
		if(ucUart1SndLength >= ucUart1BufPT)
		{
			SBUF1 = ucUart1Buf[ucUart1BufPT]; 
		}else
		{
			BANK0_SEL;
			UART485_DE = 0;				//485  Receive Data			
			BANK1_SEL;_nop_();
			ucUart1BufPT = 0;
			REN1 = 1;
		}
		TI1 = 0;
	}
	ucIdleTimerCnt = 0;
	ucPDTimerCnt = 0;			//If communication is clear the count
	ucUart1TimeoutCnt = 0;
	BANK0_SEL;
	_pop_(INSCON);
}
#endif


